package my.diplom.web.controllers;

import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.validation.Errors;
import org.springframework.validation.BindException;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import my.diplom.dao.service.EventService;
import my.diplom.dao.service.StatusService;
import my.diplom.dao.service.ResourceService;
import my.diplom.dao.service.UserService;
import my.diplom.entity.*;
import my.diplom.util.UserUtil;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.text.SimpleDateFormat;
import java.beans.PropertyEditorSupport;

/**
 * Created by IntelliJ IDEA.
 * User: gb
 * Date: 10.10.2009
 * Time: 2:56:46
 * To change this template use File | Settings | File Templates.
 */
public class EventController extends SimpleFormController{

    private EventService eventService;
    private StatusService statusService;
    private ResourceService resourceService;
    private UserService userService;

    public EventController(){
        setCommandClass(Event.class);
        setCommandName("newEvent");
        setSessionForm(false);
        setBindOnNewForm(false);
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void setEventService(EventService eventService) {
        this.eventService = eventService;
    }

    public void setStatusService(StatusService statusService) {
        this.statusService = statusService;
    }

    public void setResourceService(ResourceService resourceService) {
        this.resourceService = resourceService;
    }

     @Override
    protected Object formBackingObject(HttpServletRequest request) throws Exception {
         if (request.getParameter("eventId") != null && request.getParameter("action").equals("edit")) {
             Event event = eventService.getById(Long.parseLong(request.getParameter("eventId")));
            return event;
        } else {
             Event event = new Event();
             return event;
        }
    }

    @Override
    protected Map referenceData(HttpServletRequest httpServletRequest, Object o, Errors errors) throws Exception {
        HashMap<String, Object> model = new HashMap<String, Object>();

        List<Resource> resources = null;
        List<Event> events = null;
        if(UserUtil.isAdmin()){
            events = eventService.getAll();
            resources =  resourceService.getAll();
        } else {
            resources = resourceService.getResourcesByLogin(UserUtil.getRemoteUser());
            events = eventService.getEventsByLogin(UserUtil.getRemoteUser());
        }

        updateStatuses(events);
        model.put("events", events);
        model.put("resources", resources);
        return model;
    }

    @Override
    protected ModelAndView onSubmit(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, BindException e) throws Exception {
        Event event = (Event) o;
        event.setUser(userService.getByLogin(UserUtil.getRemoteUser()));
        event.setStatus(statusService.getByName(getEventActualStatus(event.getStartDate(), event.getFinishDate())));
        eventService.update(event);

        return new ModelAndView(new RedirectView("createEvent.htm"));
    }


     protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");


        binder.registerCustomEditor(Date.class, "startDate", new CustomDateEditor(dateFormat, false) {

        });

        binder.registerCustomEditor(Date.class, "finishDate", new CustomDateEditor(dateFormat, false) {

        });

       binder.registerCustomEditor(Status.class, "status", new PropertyEditorSupport() {

            public void setAsText(String text) {
                if (text instanceof String) {
                    if (text != null && text.trim().length() > 0){
                        Long statusId = Long.parseLong(text);
                        Status status = statusService.getById(statusId);
                        setValue(status);
                    }

                }
            }

            public String getAsText() {
                Object value = getValue();
                if (value != null) {
                    Status status = (Status) value;
                    return status.getStatusName();
                }
                return null;
            }


        });

             binder.registerCustomEditor(Resource.class, "resource", new PropertyEditorSupport() {

            public void setAsText(String text) {
                if (text instanceof String) {
                    Long resourceId = Long.parseLong(text);
                    Resource resource = resourceService.getById(resourceId);
                    setValue(resource);

                }
            }

            public String getAsText() {
                Object value = getValue();
                if (value != null) {
                    Resource resource = (Resource) value;
                    return resource.getHostName();
                }
                return null;
            }


        });

    }

    private String getEventActualStatus(Date startDate, Date finishDate){
        Date currentDate = new Date();
        Calendar calendar = Calendar.getInstance();
        if (currentDate.after(startDate) && currentDate.before(finishDate)) return "execute";
        if (currentDate.before(startDate) && currentDate.before(finishDate)) return "not_started";
        if (currentDate.after(startDate) && currentDate.after(finishDate)) return "completed";
        return "not_started";
    }


   private void updateStatuses(List<Event> events){
       for (Event e: events){
           e.setStatus(statusService.getByName(getEventActualStatus(e.getStartDate(), e.getFinishDate())));
           eventService.update(e);
       }
   }

}
